package org.surfnet.oaaas.it;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import javax.ws.rs.core.MediaType;

import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.junit.Before;
import org.junit.Test;
import org.surfnet.oaaas.model.Client;
import org.surfnet.oaaas.model.ResourceServer;
import org.surfnet.oaaas.model.ValidationErrorResponse;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.matchers.JUnitMatchers.containsString;

public class ClientResourceTestIT extends AbstractAuthorizationServerTest {
	private WebResource webResource;
	private ResourceServer resourceServer;

	private List<String> resourceServerScopes = Arrays.asList("read", "write");
	
	  @Before
	  public void prepareRestClientAndCreateResourceServer() {
	    ClientConfig config = new DefaultClientConfig();
	    config.getClasses().add(JacksonJsonProvider.class);
	    webResource = com.sun.jersey.api.client.Client.create(config)
	        .resource(baseUrl())
	        .path("admin")
	        .path("resourceServer");

	    ResourceServer newResourceServer = new ResourceServer();
	    newResourceServer.setContactName("myContactName");
	    newResourceServer.setDescription("The description");
	    newResourceServer.setName("the name" + System.currentTimeMillis());
	    newResourceServer.setKey("the-key-" + System.currentTimeMillis());
	    newResourceServer.setThumbNailUrl("http://example.com/thumbnail");
	    newResourceServer.setScopes(resourceServerScopes);

	    resourceServer = webResource
	        .type(MediaType.APPLICATION_JSON)
	        .header("Authorization", authorizationBearer(ACCESS_TOKEN))
	        .put(ResourceServer.class, newResourceServer);

	    // setup a new webResource as entry point for Client-REST-requests.
	    webResource = com.sun.jersey.api.client.Client.create(config)
	        .resource(baseUrl())
	        .path("admin")
	        .path("resourceServer")
	        .path(String.valueOf(resourceServer.getId()))
	        .path("client");
	  }
	  
	@Test
	public void getNonExisting() {
		ClientResponse response = webResource.path("-1")
				.header("Authorization", authorizationBearer(ACCESS_TOKEN))
				.get(ClientResponse.class);
		assertEquals(404, response.getStatus());
	}

	@Test
	public void getAll() {
		putSomeClient();
		putSomeClient();

		ClientResponse response = webResource.header("Authorization",
				authorizationBearer(ACCESS_TOKEN)).get(ClientResponse.class);
		assertEquals(200, response.getStatus());
		Client[] clients = response.getEntity(Client[].class);
		assertTrue(clients.length > 1);
		if (clients.length > 0) {
			for (int i = 0; i < clients.length; i++) {
				Client c = clients[i]; 
				
				ResourceServer resourceServer = c.getResourceServer();
				System.out.println(resourceServer.getName());
				System.out.println(c.getClientId()+" -> "+c.getName()+" -> "+c.getSecret()+" -> "+c.getScopes());
			}
		}
	}
	  
	private Client buildClient() {
		Client c = new Client();
		String r = UUID.randomUUID().toString();
		c.setClientId(r);
		c.setContactEmail("contact@example.com");
		c.setContactName("contact name");
		c.setName(r);
		c.setScopes(Arrays.asList("read"));
		c.setSecret(r);
		c.setDescription("Some description");
		final HashMap<String, String> attributes = new HashMap<String, String>();
		attributes.put("myKey", "myValue");
		attributes.put("myKey2", "myValue2");
		attributes.put("myKey3", "myValue3");
		c.setAttributes(attributes);
		System.out.println("---->buildClient:" + r);
		return c;
	}

	private Client putSomeClient() {
		Client c = buildClient();
		return webResource.header("Authorization", authorizationBearer(ACCESS_TOKEN)).put(Client.class, c);
	}
}
